package org.lanqiao.tjut.control;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.lanqiao.tjut.bean.UsersEntity;
import org.lanqiao.tjut.service.IUserInfoService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/user")
public class UserLoginControl {
	// 组合service层，依赖注入
	@Resource
	private IUserInfoService userService;
	
	

	/*
	 * springmvc在控制层对view层请求处理的handler方法：
	 *  
	 *   方法名：合法的命名规范即可，没有固定要求。
	 *   方法参数：方法中可以使用的参数有 基本类型、pojo类类型、httprequest、httpresponse、
	 *   httpsession、Mode、ModeMap、ModeAndView、BindingResult等类型
	 *   这些参数的初始化封装处理由springmvc框架根据请求发送方的view层的数据按照http协议请求处理要求
	 *   来进行初始化封装。
	 *   返回类型：返回的字符串是本次请求处理完成之后需要转发到的view层的视图名称。
	 *   视图名注意在pringmvc中如果配置前缀和后缀，需要将前后缀和返回的视图名进行组合，
	 *   构成本次请求使用的显示层的视图的访问url路径
	 *   返回值：
	 *        返回字符串类型：返回需要显示的view层的视图名
	 *        返回ModelAndView：ModelAndView是springmvc封转的描述view层的对象
	 *        返回Model类型：
	 *        返回Map类型：
	 *        ...（参见api：25.9.4 Supported handler method arguments）
	 *   
	 * springmvc框架中前后台之间的数据传递：  
	 * 
	 * 前台向后台：默认方式-表单的name属性和映射变量、pojo类之间一一对应（使用http请求将数据发送到服务器，springmvc框架进行数据转换映射处理）
	 * 			注解方式-@requestparam   作用在函数的参数上（有http request对象进行处理）
	 *                 
	 * 后台向前台：http相关-request、response、session                
	 *          springmvc框架封装对象： ModelAndView、Model、Map
	 *          注解方式-@ModelAttribute 作用在方法或者参数上（数据时附加在model对象上）
	 * 
	 *   
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String doLogin(HttpSession session,String userName, String userAge, Model model) {
		System.out.println(userName + "正在进行登录处理。。。");
		UsersEntity userE = userService.selectUsersInfo(2);
		String strName = (userE == null ? "" : userE.getUsername());
		System.out.println("数据库查询的用户信息为：" + strName);
		model.addAttribute("loggerName", strName);
		//将登陆成功的用户信息缓存到session中（由springmvc框架进行依赖注入提供）
		session.setAttribute("loginedUserE", userE);
		return "logined";
	}

	@RequestMapping("/login2")
	public ModelAndView doLogin2(UsersEntity userE) {
		System.out.println("从表单获取的值为：name-" + userE.getUsername());
		//创建一个modelandview对象
		ModelAndView model = new ModelAndView();
		//设置逻辑视图名
		model.setViewName("logined");
		UsersEntity userE0 = userService.selectUsersInfo(2);
		String strName = (userE0 == null ? "" : userE0.getUsername());
		System.out.println("数据库查询的用户信息为：" + strName);
		//向视图模型对象中添加 返回数据
		model.addObject("loggerName", strName);
		return model;
	}

	
	@RequestMapping("/login8")
	// @ModelAttribute("")
	public String doLogin8(HttpSession session,Model model) {
		
		UsersEntity user = new UsersEntity();
		user.setUsername("小明");
		user.setUserage(20);
		model.addAttribute("userE", user);
		//将登陆成功的用户信息缓存到session中（由springmvc框架进行依赖注入提供）
		session.setAttribute("loginedUserE", user);
		
		return "logined";
	}

	/*
	 * 注意：在需要进行验证的参数前 加 @Validated注解
	 *      在需要验证的参数后加 BindingResult br
	 *      且被验证的对象必须夹在其中
	 * 		验证未通过的错误信息可以从br变量中获取
	 *      通过br可以获得验证是否通过的结果
	 */
	@RequestMapping("/login9")
	public String doLogin9(@Validated @ModelAttribute("userE") UsersEntity userE,
			BindingResult br,String strUsername) {
		//检测验证是否通过
		if(br.hasErrors()){
			// 获取验证失败的信息
			List<ObjectError> lstErrors = br.getAllErrors();
			for (ObjectError objE : lstErrors) {
				// 打印错误信息
				System.out.println(objE.getDefaultMessage());
			}
			//TODO 扩展作业：如何打印出国际化的错误提示信息？
			// 阻止处理流程继续向下处理，返回到前台页面
			return "logined";
		}
		
		// 验证通过之后，本次请求的业务逻辑处理
		
		return "test";
	}
}
